<template>
  <el-card v-loading="loading">
    <el-tree
      ref="eltree"
      :data="dataSource"
      node-key="menuPath"
      :expand-on-click-node="false"
      :props="{ label: 'menuName' }"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <span class="flex items-center">
            <IconifyIconOffline v-if="data.menuIcon" :icon="data.menuIcon" class="mr-1" />
            <span>{{ data.menuName }}</span>
            <el-tag v-if="data.menuPath" size="small" type="primary" class="ml-2">{{ data.menuPath }}</el-tag>
          </span>
          <span>
            <el-button
              v-if="data.type == 0"
              v-perms="'/system/menu/add'"
              size="small"
              type="primary"
              @click="append(data)"
            >
              添加
              <IconifyIconOffline icon="ep:circle-plus" class="ml-1" />
            </el-button>
            <el-button
              v-if="data.id > 0"
              v-perms="'/system/menu/update'"
              size="small"
              type="primary"
              @click="update(node, data)"
            >
              修改
              <IconifyIconOffline icon="ep:edit" class="ml-1" />
            </el-button>
            <el-button
              v-if="data.id > 0"
              v-perms="'/system/menu/del'"
              size="small"
              type="primary"
              @click="remove(node, data)"
            >
              删除
              <IconifyIconOffline icon="ep:delete" class="ml-1" />
            </el-button>
          </span>
        </span>
      </template>
    </el-tree>
    <menu-add ref="menuAdd" @save-success="addMenuSuccess" />
    <menu-update ref="menuUpdate" @save-success="updateMenuSuccess" />
  </el-card>
</template>
<script setup lang="ts">
import { delMenu, getMenuTreeList } from "@/api/user/menuApi";
import { ref, shallowReactive, shallowRef, useTemplateRef } from "vue";
import MenuAdd from "./MenuAdd.vue";
import MenuUpdate from "./MenuUpdate.vue";
import { IconifyIconOffline } from "@/components/ReIcon/index";
import { accessTree } from "@/utils/tree";
import { msgConfirm, successMsg } from "@/utils/message";
const dataSource = ref<ShopTreeMenuVo[]>([]);
const loading = ref(true);
let map = new Map<string, ShopTreeMenuVo>();
getMenuTreeList().then(res => {
  if (res.code == RESPONSE_CODE.SUCCESS) {
    loading.value = false;
    let rootMenu: ShopTreeMenuVo = {
      menuName: "后台管理",
      menuPath: "",
      menuIcon: "ep:monitor",
      type: 0,
      children: res.data,
      id: -1,
      parentMenuId: -1
    };
    dataSource.value = [rootMenu];
    accessTree(dataSource.value, v => {
      map.set(v.menuPath, v as ShopTreeMenuVo);
    });
  }
});

const eltree = useTemplateRef("eltree");
const menuAdd = useTemplateRef("menuAdd");
const menuUpdate = useTemplateRef("menuUpdate");
function append(data: ShopTreeMenuVo) {
  menuAdd.value.show(data, getPatentPathName(data));
}
function remove(node, data) {
  msgConfirm("确认删除吗？", async () => {
    let res = await delMenu({ menuId: data.id });
    if (res.code == RESPONSE_CODE.SUCCESS) {
      successMsg("删除成功");
      eltree.value.remove(data);
    }
    return res;
  });
}

function update(node, data: ShopTreeMenuVo) {
  menuUpdate.value.show(data, getPatentPathName(data));
}

function updateMenuSuccess(data: ShopTreeMenuVo) {
  let exist = map.get(data.menuPath);
  exist.menuIcon = data.menuIcon;
  exist.menuName = data.menuName;
}

function addMenuSuccess(data: ShopTreeMenuVo) {
  map.set(data.menuPath, shallowReactive(data));
  eltree.value.append(data, data.menuPath.substring(0, data.menuPath.lastIndexOf("/")));
}
function getPatentPathName(data: ShopTreeMenuVo) {
  let path = data.menuPath;
  let parent: string[] = [];
  let index = -1;
  parent.push(map.get(path).menuName);
  while ((index = path.lastIndexOf("/")) > 0) {
    path = path.substring(0, index);
    parent.push(map.get(path).menuName);
  }
  return parent.reverse().join(" / ");
}
</script>
<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
